package com.ews.onlineexchange.service;

import java.io.IOException;
import java.util.List;

import javax.enterprise.inject.Model;
import javax.inject.Inject;
import javax.persistence.EntityManager;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.query.dsl.QueryBuilder;

import com.ews.onlineexchange.model.Article;
import com.ews.onlineexchange.model.Bulletin;
import com.ews.onlineexchange.model.DataEntity;
import com.ews.onlineexchange.model.ServiceSupplier;

@Model
public class NewFtService extends FullTextEntityQuery<DataEntity> {
	
	private static final long serialVersionUID = 1L;

	@Inject
	EntityManager entityManager;
	
	private String searchString ;	
	
	
	public NewFtService() {
		super();
		setMaxResults(super.MAX_RESULTS_NORMAL);
	}

	@Override
	public List<DataEntity> getResultList() {
		List<DataEntity> results = super.getResultList();
		SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<b><font color=\"red\">", "</font></b>");
		QueryScorer qs = new QueryScorer(createLuceneQuery());
		Highlighter highlighter = new Highlighter( formatter, qs);
		Analyzer analyzer = new SmartChineseAnalyzer();
		try {
			for (DataEntity dataEntity : results) {
				String findResult = highlighter.getBestFragment(analyzer, searchString, dataEntity.getHighLightTitle());
				if (findResult != null)
					dataEntity.setHighLightTitle(findResult);
				
				String highLightContent = dataEntity.getHighLightContent();
				String hContent = highlighter.getBestFragment(analyzer, searchString, highLightContent);
				if (hContent != null)
					dataEntity.setHighLightContent(hContent);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InvalidTokenOffsetsException e) {
			e.printStackTrace();
		}
		return results;
	}
	
	public String getSearchString() {
		return searchString;
	}

	public void setSearchString(String searchString) {
		this.searchString = searchString;
	}

	@Override
	protected FullTextQuery createQuery() {
		FullTextEntityManager ftem = getFullTextEntityManager();
		return ftem.createFullTextQuery(createLuceneQuery(), Article.class, Bulletin.class,ServiceSupplier.class);
	}

	@Override
	protected Query createLuceneQuery() {
		String searchQuery = this.searchString;
		FullTextEntityManager ftem = getFullTextEntityManager();
		
		QueryBuilder articleQb = ftem.getSearchFactory().buildQueryBuilder().forEntity(Article.class).get();
		Query stat = articleQb.keyword().onField("stat").matching("1").createQuery();
		Query articleDelFlag = articleQb.keyword().onField("delFlag").matching("0").createQuery();
		Query articleQuery = articleQb.keyword().filteredBy(stat).filteredBy(articleDelFlag).onFields("title","articleData.content").matching(searchQuery).createQuery();		
		
		QueryBuilder bulletinQb = ftem.getSearchFactory().buildQueryBuilder().forEntity(Bulletin.class).get();
		Query bulletinDelFlag = bulletinQb.keyword().onField("delFlag").matching("0").createQuery();
		Query auditResult = bulletinQb.keyword().onField("auditResult").matching(true).createQuery();
		Query bulletinQuery = bulletinQb.keyword().filteredBy(auditResult).filteredBy(bulletinDelFlag)
				.onFields("title", "projectName").matching(searchQuery).createQuery();
		
		QueryBuilder supplierQb = ftem.getSearchFactory().buildQueryBuilder().forEntity(ServiceSupplier.class).get();
		Query auditted = supplierQb.keyword().onField("auditted").matching(true).createQuery();
		Query supplierDelFlag = supplierQb.keyword().onField("delFlag").matching("0").createQuery();
		Query supplierQuery = supplierQb.keyword().filteredBy(auditted).filteredBy(supplierDelFlag).onFields("address","cnname","intro").matching(searchQuery).createQuery();
//		supplierQuery.sort( supplierQb.sort().byField( "numberOfReviews" ).desc().createSort() );
		
		org.apache.lucene.search.Query combineQuery = articleQb.bool().should(articleQuery).should(bulletinQuery).should(supplierQuery).createQuery();
		return combineQuery;
	}
	
	
	
}
